#include "sgmexporter.h"

void SGMExporter::CollectMesh(IGameScene *igame_scene, IGameNode *igame_node, IGameMesh *igame_mesh, SGMDataCollector *sgm_data)
{
	igame_mesh ->InitializeData();

	Scene3DMesh *mesh = new Scene3DMesh();
	mesh ->id = igame_node ->GetNodeID();
	mesh ->materialIndex = igame_node ->GetMaterialIndex();

	CollectFaces(igame_mesh, mesh, sgm_data);
	CollectVerts(igame_mesh, mesh, sgm_data);
	CollectNormals(igame_mesh, mesh, sgm_data);
	CollectCoords(igame_mesh, mesh, sgm_data);

	sgm_data ->AddMesh(mesh);
}

void SGMExporter::CollectFaces(IGameMesh *igame_mesh, Scene3DMesh *mesh, SGMDataCollector *sgm_data)
{
	mesh ->faces_count = igame_mesh ->GetNumberOfFaces();
	mesh ->faces = new Scene3DFace[mesh ->faces_count];

	for (int i = 0; i < mesh ->faces_count; i++)	
	{
		FaceEx *igame_face = igame_mesh ->GetFace(i);

		mesh ->faces[i].vert_i[0] = igame_face ->vert[0];
		mesh ->faces[i].vert_i[1] = igame_face ->vert[1];
		mesh ->faces[i].vert_i[2] = igame_face ->vert[2];

		mesh ->faces[i].norm_i[0] = igame_face ->norm[0];
		mesh ->faces[i].norm_i[1] = igame_face ->norm[1];
		mesh ->faces[i].norm_i[2] = igame_face ->norm[2];

		mesh ->faces[i].coord_i[0] = igame_face ->texCoord[0];
		mesh ->faces[i].coord_i[1] = igame_face ->texCoord[1];
		mesh ->faces[i].coord_i[2] = igame_face ->texCoord[2];
	}
}

void SGMExporter::CollectVerts(IGameMesh *igame_mesh, Scene3DMesh *mesh, SGMDataCollector *sgm_data)
{
	mesh ->verticles_count = igame_mesh ->GetNumberOfVerts();
	mesh ->verticles = new Scene3DVector[mesh ->verticles_count];

	for (int i = 0; i < mesh ->verticles_count; i++)	
	{
		Point3 vert = igame_mesh ->GetVertex(i, false);

		mesh ->verticles[i].x = vert.x;
		mesh ->verticles[i].y = vert.y;
		mesh ->verticles[i].z = vert.z;
	}
}

void SGMExporter::CollectNormals(IGameMesh *igame_mesh, Scene3DMesh *mesh, SGMDataCollector *sgm_data)
{
	mesh ->normals_count = igame_mesh ->GetNumberOfNormals();
	mesh ->normals = new Scene3DVector[mesh ->normals_count];

	for (int i = 0; i < mesh ->normals_count; i++)	
	{
		Point3 norm = igame_mesh ->GetNormal(i, false);

		mesh ->normals[i].x = norm.x;
		mesh ->normals[i].y = norm.y;
		mesh ->normals[i].z = norm.z;
	}
}

void SGMExporter::CollectCoords(IGameMesh *igame_mesh, Scene3DMesh *mesh, SGMDataCollector *sgm_data)
{
	mesh ->tex_coords_count = igame_mesh ->GetNumberOfTexVerts();
	mesh ->tex_coords = new Scene3DTexCoord[mesh ->tex_coords_count];

	for (int i = 0; i < mesh ->tex_coords_count; i++)	
	{
		Point2 coord = igame_mesh ->GetTexVertex(i);

		mesh ->tex_coords[i].u = coord.x;
		mesh ->tex_coords[i].v = coord.y;
	}
}

void SGMExporter::ExportNode(IGameScene *igame_scene, IGameNode *igame_node, SGMDataCollector *sgm_data)
{
	IGameObject *igame_object = igame_node ->GetIGameObject();

	switch (igame_object ->GetIGameType())
	{
	case IGameObject::IGAME_MESH:
		CollectMesh(igame_scene, igame_node, (IGameMesh *)igame_object, sgm_data);
		break;
	}

	igame_node ->ReleaseIGameObject();

	int node_childs_count = igame_node ->GetChildCount();

	for (int i = 0; i < node_childs_count; i++)
		ExportNode(igame_scene, igame_node ->GetNodeChild(i), sgm_data);

	StepProgress();
}

void SGMExporter::ExportObjects(IGameScene *igame_scene, SGMDataCollector *sgm_data)
{
	int totalNodeCount = igame_scene ->GetTotalNodeCount();
	SetProgressSteps(totalNodeCount);

	int c_top_nodes = igame_scene ->GetTopLevelNodeCount();

	for (int i = 0; i < c_top_nodes; i++)
		ExportNode(igame_scene, igame_scene ->GetTopLevelNode(i), sgm_data);
}

void SGMExporter::ExportScene(SGMDataCollector *sgm_data)
{
	IGameScene *igame_scene = GetIGameInterface();
	IGameConversionManager *cm = GetConversionManager();
	cm ->SetCoordSystem(IGameConversionManager::IGAME_OGL);

	igame_scene ->InitialiseIGame(false);
	igame_scene ->SetStaticFrame(0);

	ExportObjects(igame_scene, sgm_data);

	igame_scene ->ReleaseIGame();
}

bool SGMExporter::DoExport(const TCHAR *name, ExpInterface *ei, Interface *max_interface)
{
	file_name = (char*)name;

	SGMDataCollector *sgm_data = new SGMDataCollector();
	ExportScene(sgm_data);
	sgm_data ->SaveToFile(name);

	delete sgm_data;

	return 1;
}

void SGMExporter::RegisterObserver(IProgressObserver *observer)
{
	observers.push_back(observer);
}

void SGMExporter::UnregisterObserver(IProgressObserver *observer)
{
	//TODO:
}

void SGMExporter::SetProgressSteps(int progressSteps)
{
	std::vector<IProgressObserver*>::iterator i;
	for (i = observers.begin(); i != observers.end(); i++)
		(*i) ->SetProgressSteps(this, progressSteps);
}

void SGMExporter::StepProgress()
{
	std::vector<IProgressObserver*>::iterator i;
	for (i = observers.begin(); i != observers.end(); i++)
		(*i) ->StepProgress(this);
}

const char *SGMExporter::GetResultMessage()
{
	return "";
}